package com.hspedu.seckill.rabbitmq;

import cn.hutool.json.JSONUtil;
import com.hspedu.seckill.config.RabbitMQSecKillConfig;
import com.hspedu.seckill.entity.User;
import com.hspedu.seckill.model.dto.SeckillMessage;
import com.hspedu.seckill.model.vo.GoodsVo;
import com.hspedu.seckill.service.GoodsService;
import com.hspedu.seckill.service.OrderService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;

/**
 * @author: xujiabing
 * @date: 2024-12-18 21:04
 * @description: 秒杀商品-消息消费者
 */
@Service
@Slf4j
public class MQReceiverConsumer {

    @Resource
    private GoodsService goodsService;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private OrderService orderService;

    @RabbitListener(queues = RabbitMQSecKillConfig.QUEUE)
    public void queue(String message, Message amqpMessage, Channel channel) {
        log.info("接收到消息 = {}", message);

        try {
            // 将string 反序列化 为 SeckillMessage 对象
            SeckillMessage seckillMessage = JSONUtil.toBean(message, SeckillMessage.class);
            // 秒杀用户
            User user = seckillMessage.getUser();
            // 秒杀商品id
            Long goodsId = seckillMessage.getGoodsId();
            // 获取到goodsVo
            GoodsVo goodsVo = goodsService.findGoodsVoByGoodsId(goodsId);
            // 开始执行下单
            orderService.seckill(user, goodsVo);

            // 手动ACK
            channel.basicAck(amqpMessage.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            log.error("处理消息时发生错误: ", e);
            try {
                // 手动NACK
                channel.basicNack(amqpMessage.getMessageProperties().getDeliveryTag(), false, true);
            } catch (IOException ioException) {
                log.error("发送NACK时发生错误: ", ioException);
            }
        }

    }

}
